home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-05-21 | 19.5 KB | 626 lines | [TEXT/ttxt] |
- --<<<-
- -- Filename:DocDemo.sx
-
- -- Other Files Required:
- -- seadoc.sxt (if you want to see the sample document)
-
- -- Purpose:
- -- The functions in docfns.sx create a document that can have two
- -- kinds of pages: a definiton page and a movie page.
- -- You can move through the pages in the document by clicking on
- -- bars at the side of each page.
- -- A definition page has a heading, description and picture.
- -- A movie page has a heading, description, movie, and copyright info
- -- and also play and stop buttons for controlling the movie.
-
- -- A document of this kind can be created for any set of input
- -- objects that conform to the standards required by the document.
- -- For a movie page, the input object must have heading,
- -- description, movie and copyrightInfo ivs.
- -- Heading, description, and copyrightInfo
- -- ivs must contain Text.
- -- Picture iv must contain a bitmap.
- -- For a definition page, the input object must have heading,
- -- description and picture ivs. Heading and description
- -- ivs must contain Text.
- -- Movie iv must contain an interleaved movie player.
-
- -- Specialized Classes:
- -- SpecialPage has an iv that has a dataObject iv that points to
- -- the object holding the data for this page.
- -- MoviePushButton has an iv that points to the movie player
- -- controlled by the pushbutton.
- -- MyDocument has a currentMovie iv that knows which movie
- -- is currently playing, if any
-
- -- Instructions to User:
- -- Load docfns.sx, create the objects to hold the data for the
- -- pages, then call makeDocument to create a document. Append the
- -- document to an open window and call "goto docname 1"
- -- to open the first page.
- -- Click on the bar on the right hand side of the page to move
- -- to the next page, and click on the bar on the left hand side of
- -- the page to move to the previous page.
-
- -- Alternatively load makeDoc.sx, which files in docfns.sx
- -- then calls createDoc1, whch calles makeDocument,
- -- to make a sample document and save it in seadoc.sxt.
-
-
-
-
-
-
- -- Author:
- -- Jocelyn Becker.
- -- Modified on: 11/13/95 to update to 1.5
-
- ------------------------------------------------------------------------
-
- -- Document Templates Test
-
-
-
- -- Define some custom colors
-
-
- global constant blueBrush := new brush color: blueColor
- global constant skyBlueBrush := new brush \
- color: (new RGBColor red:80 green:180 blue:250)
- global constant darkerBlueBrush := new brush \
- color:(new RGBColor red:20 green:120 blue:250)
- global constant otherBlueBrush := new brush \
- color:(new RGBColor red:140 green:180 blue:250)
- global constant greenBrush := new brush color: greenColor
- global constant middleGreenBrush:= new brush \
- color:(new RGBColor red:160 green:250 blue:160)
-
-
-
-
-
-
- -- Make the background layer
- -- This layer contains the outline of the page, the bars
- -- on the left and right that let you move through the document,
- -- and also text presenters for the heading for the page and the page number.
- -- pageWidth and pageHeight are the width and height of the page.
-
- -- the margin is the distance between the edge of the page
- -- and any content (such as the back/forward buttons)
- -- the innerMargin is the margin at which contents other
- -- than the back/forward buttons start
-
- function makeMargin pageWidth -> (pageWidth * 0.1)
- function makeInnerMargin pageWidth -> (pageWidth * 0.22)
-
-
- function makeBackgroundLayer pageWidth pageHeight ->
- (
- local margin := makeMargin pageWidth
- local innerMargin := makeInnerMargin pageWidth
-
- -- the smallwidth is the width of the back and forward
- -- buttons and the pageNumber element
- local smallwidth := (innermargin - margin) * 0.66
-
- local smallRect := new rect x1:0 y1:0 x2:smallwidth y2:smallwidth
-
-
- -- Create a Text Presenter that holds the pagenumber
-
- local pageNumberText := (new TextPresenter \
- boundary: smallRect stroke:greenBrush \
- fill: middleGreenBrush \
- target: ("" as Text))
- pageNumberText.inset := new point x:0 y:2
- setDefaultAttr pageNumberText @font \
- (new PlatformFont name:"Palatino")
- setDefaultAttr pageNumberText @size 12
- setDefaultAttr pageNumberText @alignment @center
-
-
- -- Find the page number.
- -- The document's cursor indicates
- -- the current position in the doc
-
- local pageNumberElement := new pageElement\
- presenter: pageNumberText \
- target: (e -> (findParent e Document).cursor as Text )
- pageNumberElement.x := (pageWidth - smallWidth) / 2
- pageNumberElement.y := pageHeight - (margin + smallWidth)
-
-
- -- Create the Text Presenter for the heading
- local headingText := (new TextPresenter \
- boundary: (new rect \
- x2:(pageWidth - (2 * innerMargin)) y2:35) \
- stroke: blackBrush target: ("" as Text) \
- fill: skyBlueBrush)
- headingText.inset := new point x:10 y:10
- setDefaultAttr headingText @font \
- (new PlatformFont name:"Helvetica")
- setDefaultAttr headingText @size 18
- setDefaultAttr headingText @alignment @center
-
- local headingElement := new pageElement presenter: headingText \
- target: (e -> getfirst (getParentData e SpecialPage))
- headingElement's x := innerMargin
- headingElement's y := margin
-
-
-
- -- Create the forward and backward page buttons
- local buttonrect := new rect x2:smallwidth \
- y2:(pageHeight - (2 * margin))
-
- local forwardUp := new twoDshape boundary: buttonRect \
- fill: skyBlueBrush stroke: otherBlueBrush
- local forwardDown := new twoDshape boundary: buttonRect \
- fill: darkerBlueBrush
-
- local backwardUp := new twoDshape boundary: buttonRect \
- fill: skyBlueBrush stroke: otherBlueBrush
- local backwardDown := new twoDshape boundary: buttonRect \
- fill: darkerBlueBrush
-
-
- local forwardButton := new pushbutton \
- releasedPresenter:forwardUp \
- pressedPresenter: forwardDown
- local backwardButton := new pushbutton \
- releasedPresenter:backwardup \
- pressedPresenter: backwarddown
-
- -- When a pushbutton is pressed, its activateAction function is called
- -- with the arguments pushbutton.authordata and pushbutton.
- -- Here we want to find the document containing the pushButton,
- -- so call findParent on the object that is presenting the pushbutton
-
- forwardButton.activateAction := \
- (a b -> forward (findParent (b.presentedBy) Document))
-
- backwardButton.activateaction := \
- (a b -> backward (findParent (b.presentedBy) Document))
-
-
- -- put the push buttons inside page elements
- local forwardButtonElement := new pageelement \
- presenter: forwardButton
- forwardButtonElement.x := (pageWidth - (margin + smallwidth))
- forwardButtonElement.y := margin
-
- local backwardButtonElement := new pageelement \
- presenter:backwardButton
- backwardButtonElement.x := margin
- backwardButtonElement.y := margin
-
- -- Create a pagelayer that holds background information
- local bkgdLayer := new pagelayer \
- boundary:(new rect x2:pageWidth y2:pageHeight)
-
- bkgdLayer.stroke := blueBrush
- append bkgdLayer pageNumberElement
- append bkgdLayer forwardButtonElement
- append bkgdLayer backwardButtonElement
- append bkgdLayer headingElement
-
-
- -- Make an actuator controller to control
- -- the buttons in the background layer
- local docController := new actuatorController space:bkgdLayer
-
- append doccontroller forwardButtonElement
- append doccontroller backwardButtonElement
-
- -- return the background layer
- bkgdLayer
- )
-
- print "made the backgroundlayer function"
- -- Make the definition layer, which contains text definition
-
- function makeDefinitionLayer pageWidth pageHeight->
- (
- local margin := makeMargin pageWidth
- local innerMargin := makeInnerMargin pageWidth
-
- -- Create the Text Presenter that presents the info
- local infoText := (new TextPresenter \
- boundary: (new rect x2: (pageWidth - (2 * innerMargin)) y2: 80) \
- stroke:blackbrush target:("" as Text))
-
- infoText.inset := new point x:10 y:10
- setDefaultAttr infoText @font \
- (new PlatformFont name:"Palatino")
- setDefaultAttr infoText @size 12
- setDefaultAttr infoText @leading 14
- setDefaultAttr infoText @alignment @flush
-
-
- -- put the info text presenter into a page element
- local infoElement := new pageElement presenter : infoText \
- target: (e -> getsecond (getParentData e SpecialPage))
- infoElement.x := innerMargin
- infoElement.y := innermargin + 15
-
- -- create a page layer
- local definitionLayer := new pagelayer \
- boundary:(new rect x2:pageWidth y2:pageHeight)
- append definitionLayer infoElement
-
- -- return the definition page layer
- definitionLayer
- )
-
- print "made makeDefinitionLayer"
-
- -- Make the picture layer
- function makePictureLayer pageWidth pageHeight ->
- (
- local margin := makeMargin pageWidth
- local innerMargin := makeInnerMargin pageWidth
-
- -- Create the box that displays the picture
- local picPresenter := \
- new TwoDShape fill:blackbrush stroke:blackbrush
-
-
- local picElement := \
- new pageElement presenter: picPresenter \
- target: (e -> getThird (getParentdata e SpecialPage))
- picElement.x := innerMargin
- picElement.y := 160 + margin
-
- -- Make a page layer for the picture
- local pictureLayer := new pagelayer \
- boundary:(new rect x2:pageWidth y2:pageHeight)
-
- append pictureLayer picElement
-
- -- return the picture layer
- pictureLayer
- )
-
- print "made makePictureLayer"
-
- -- define a subclass of Document
- -- this document knows what movie,
- -- if any, is currently playing
- class MyDocument (Document)
- instance variables
- currentMovie
- end
-
-
-
-
- -- Make a class for the Pushbutton that controls the movie
-
- class MoviePushbutton (PushButton)
- instance variables
- movieElement
- end
-
- -- Define the methods used by the movie button
-
- method playMovie button {class MoviePushButton} ->
- (
- -- the movieElement is the first element in the group space
- local thisMovieElement := button.movieElement
- local doc := findparent thisMovieElement.presentedBy Document
- local movie := thisMovieElement[1]
-
- stop movie
- gotobegin movie
- playprepare movie 1
- play movie
-
- -- keep track of which movie is currently playign
- doc.currentMovie := movie
- )
-
-
- method stopMovie button {class MoviePushButton} ->
- (
- -- the movie is the first element in the group space
- local thisMovieElement := button.movieElement
- local doc := findparent thisMovieElement.presentedBy Document
-
- local movie := thisMovieElement[1]
- stop movie
- gotobegin movie
- playprepare movie 1
-
- -- no movie is currently playing
- doc.currentMovie := undefined
- )
-
- print "Defined the MoviePushButton class"
-
- class MovieGroupSpace (GroupSpace)
- end
-
- -- define the target setter for MovieGroupSpace
- -- so that when you add a value to the target iv
- -- it effectively adds the target to the group
-
- method targetSetter self {class MovieGroupSpace} value ->
- ( emptyout self
- prepend self value
- )
-
-
- -- define the getter also
- method targetGetter self {class MovieGroupSpace} ->
- (self[1] )
-
- print "Defined the MovieGroupSpace class"
-
-
-
- -- Make a pagelayer for the movie.
- -- This layer contains the movie element and the buttons
- -- to control the movie.
-
- function makeMovieLayer pageWidth pageHeight ->
- (
- local margin := makeMargin pageWidth
- local innerMargin := makeInnerMargin pageWidth
- local buttonWidth := 35
- local buttonHeight := buttonWidth * 0.75
-
-
- local movieElement := new pageElement \
- presenter: (new MovieGroupSpace) \
- target: (e -> (getNth (getParentdata e SpecialPage) 3))
- movieElement.x := innerMargin
- movieElement.y := 160 + margin
-
- -- Create the Movie Control Buttons
- local movieButtonRect := new rect x2: buttonWidth y2: buttonHeight
-
- local playUp := new textPresenter boundary: movieButtonRect \
- fill: otherBlueBrush stroke: BlueBrush \
- target: ("Play" as Text)
- playUp.inset := new point x:0 y:4
- setDefaultAttr playUp @font (new PlatformFont name:"Helvetica")
- setDefaultAttr playUp @alignment @center
-
- local playdown := new twoDshape \
- boundary:movieButtonRect \
- fill:darkerBlueBrush
-
- -- Create the pushbutton to play the movie.
-
- local playButton:= new MoviePushbutton \
- releasedPresenter: playUp pressedPresenter: playdown
- playButton.movieElement := movieElement
-
- -- When a push button is pressed,
- -- its activateAction function is called
- -- with the arguments pushbutton.authorData and pushbutton.
- -- Here we want to call the playMovie function on the pushbutton
-
- playButton.activateAction := (a b -> playMovie b)
-
- playButton.x := innerMargin
- playButton.y := (pageHeight - margin - playbutton.height )
-
- -- make the shadow for the playButton
- local playShadow := new twodshape fill: darkerBlueBrush \
- stroke: darkerBlueBrush target: movieButtonRect
- playShadow.x := playButton.x + 2
- playShadow.y := playButton.y - 2
-
- -- make the stop button
- local stopUp := new textPresenter boundary:movieButtonRect \
- fill: otherBlueBrush stroke: BlueBrush target: ("Stop" as Text)
- setDefaultAttr stopUp @font (new PlatformFont name:"Helvetica")
- setDefaultAttr stopUp @alignment @center
- stopUp.inset := new point x:0 y:4
-
- local stopDown := new twoDshape boundary: movieButtonRect \
- fill: darkerBlueBrush
-
- local stopButton := new MoviePushbutton \
- releasedPresenter: stopUp pressedPresenter: stopDown
- stopButton.movieElement := movieElement
- stopButton.activateaction := (a b -> stopmovie b)
- stopButton.x := (pageWidth - (innerMargin + buttonWidth))
- stopButton.y := pageHeight - stopbutton.height - margin
-
- -- make the shadow for the stop button
- local stopShadowButton := new twoDshape fill: darkerBlueBrush \
- stroke: darkerBlueBrush target: movieButtonRect
- stopShadowButton.x := stopButton.x + 2
- stopShadowButton.y := stopButton.y - 2
-
- -- make a box to show any required copyright notices
- local copyRightBox := new TextPresenter \
- boundary:(new rect \
- x2: (pagewidth - innermargin) y2:15) \
- target:""
- setdefaultAttr copyRightBox @font (new PlatformFont name:"Times")
- setdefaultAttr copyRightBox @size 11
-
- -- put the copy right text presenter into a page element
- local copyrightElement := new pageElement presenter: copyRightBox \
- target: (e -> (getNth (getParentdata e SpecialPage) 4))
-
- copyrightElement.x := innermargin
- copyrightElement.y := pageheight - 20
-
- -- Make a page layer for the moviepage
- local movieLayer := new PageLayer \
- boundary:(new rect x2:pageWidth y2:pageHeight)
- append movieLayer movieElement
- append movieLayer playButton
- append movieLayer stopButton
- append movieLayer playShadow
- append movieLayer stopShadowButton
- prepend movieLayer copyrightElement
-
- -- Make an actuator controller to control the buttons
- -- on the movieLayer
-
- local movieController := new actuatorController space:movieLayer
- append movieController playButton
- append movieController stopButton
-
- -- return the movie layer
- movieLayer
- )
-
- -- Make a new Page subclass that points to the object
- -- holding data for the page
- class SpecialPage (Page)
- instance variables
- dataObject
- end
-
- print "defined the SpecialPage class"
-
- -- define the changePage method for specialPage so
- -- that whenever the page changes, if a movie is
- -- playing, it stops automatically
- method changePage self {class SpecialPage} newpage ->
- (
- local doc := findparent self document
- if (doc.currentMovie != undefined)
- do (stop doc.currentmovie
- doc.currentMovie := undefined
- )
- nextMethod self newpage
- )
-
-
-
- print "made makeMovieLayer"
-
-
- -- makeTemplate makes a page template from a list of page layers
- -- Call this function with a list of the layers that make up the template
- -- It uses the boundary of the first layer in the list as the boundary
- -- for the page template
-
- function makeTemplate layerList ->
- (
- local template1 := new pageTemplate boundary:layerlist[1].boundary
- for i in layerList do append template1 i
- template1
- )
-
-
- -- The following function adds a "movie page" to a document
- -- A "movie page" has a heading, description, movie
- -- and buttons to control the movie
- -- The doc arg must be an existing document.
- -- The dataobject arg must be an object that has Text values in its
- -- heading and description instance variables, and whose
- -- movie instance variable must point to a target for a movie.
- -- The template arg must be a "movie page template", that is,
- -- an object returned by the function makeTemplate, whose input collection
- -- is a background layer, a definition layer and a movie layer.
- -- These layers can in turn can be created by
- -- the function makebackgroundlayer,
- -- makedefinitionlayer and makemovielayer respectively
- -- Note that you can use a single template object for multiple pages -
- -- you do not need to create a new one for each page
-
- function appendMoviePage doc dataobject template ->
- (
- -- The new page has the same boundary as its template
- local newPage := new specialPage frame:template \
- boundary:(template.boundary)
-
- -- Set the value of the page's dataobject instance variable
- newpage.dataobject := dataobject
-
- -- Set the target of the page to be an anonymous function that
- -- returns an array of the heading, description and movie,
- -- which are found on the dataobject
- newpage.target := (p -> #(p.dataObject.heading,
- p.dataobject.description,
- p.dataobject.movie,
- p.dataobject.copyrightInfo))
- append doc newpage
- -- return the new page
- newpage
- )
-
- -- The following function adds a "definition page" to a document.
- -- A "definition page" has a heading, a description and a bitmap
- -- The doc arg must be an existing document
- -- The dataobject must be an object that has Text values in its
- -- heading and description instance variables, and a
- -- bitmap in its picture instance variable.
- -- The template arg must be a "definition template", that is ,
- -- an object returned by the makeTemplate function whose input
- -- collection is a background layer, a definition layer and a picture layer
- -- which can be created by the functions makebackgroundlayer,
- -- makedefinitionlayer and makepicturelayer respectively.
-
- function appendDefinitionPage doc dataObject template ->
- (
- -- The new page has the same boundary as its template
- local newpage := new specialPage frame:template \
- boundary:(template.boundary)
- newpage.dataObject := dataObject
-
- -- Set the target of the page to be an anonymous function that
- -- returns an array containing the heading, description
- -- and picture, which are found on the dataObject
- newpage.target:= (p -> #(p.dataObject.heading,
- p.dataObject.description,
- p.dataObject.picture))
- append doc newpage
- -- return the new page
- newpage
- )
-
- -- Example function that creates a document
- -- You would modify this to suit your needs
-
- -- Note that you must generate the list of objects to use
- -- as definitionObjectList and movieObjectList
-
- -- definitionObjectList should be an array of objects
- -- that each have Text values in their heading and description
- -- instance variables, and a bitmap in their picture instance variable.
-
- -- movieObjectList should be an array of objects
- -- that each have Text values in their heading and description
- -- instance variables, and a suitable target for a movieplayer
- -- in their movie instance variable.
-
- -- pageWidth and pageHeight are the width and height of the page
-
-
- function makeDocument pageWidth pageHeight \
- definitionObjectList movieObjectList ->
- (
- -- Make the page layers
- local bkgdLayer := makeBackgroundLayer (pageWidth, pageHeight)
- local definitionLayer := makeDefinitionLayer (pageWidth, pageHeight)
- local movieLayer := makeMovieLayer (pageWidth, pageHeight)
- local pictureLayer := makePictureLayer (pageWidth, pageHeight)
-
- -- Make the page templates
- local glossaryTemplate := \
- makeTemplate #(pictureLayer, definitionLayer, bkgdLayer)
- local movieTemplate := \
- makeTemplate #(movieLayer, definitionLayer, bkgdLayer)
-
- -- Create the document and append pages to it.
- local doc := new MyDocument
- for i in definitionObjectList do
- appendDefinitionPage doc i glossaryTemplate
-
- for i in movieObjectList do
- appendMoviePage doc i movieTemplate
-
- -- returnt the document
- doc
- )
-